const http = require('http');
const port = process.env.PORT || 1337;
const httpProxy = require('http-proxy');
const watch = require('./watch');
const ServiceModel = require('./service');
const RouteConfig = require('./route-config');
const cache = require('./cache');
const ProxyMatch = require('./proxy-match');

var showMem = function () {
    var mem = process.memoryUsage();
    var format = function (bytes) {
        return (bytes / 1024 / 1024).toFixed(2) + 'MB';
    };
    console.log('Process: heapTotal ' + format(mem.heapTotal) + ' heapUsed ' + format(mem.heapUsed) + ' rss ' + format(mem.rss));
    console.log('----------------------------------------');
};
// 创建代理实例
const proxy = httpProxy.createProxyServer();

const cluster = require('cluster');
const numCPUs = require('os').cpus().length;
if (cluster.isMaster) {
    for (var i = 0; i < numCPUs; i++) {
        cluster.fork();
    }
    cluster.on('exit', (worker, code, signal) => {
        //console.log(`worker ${worker.process.pid} died`);
    });
} else {
    http.createServer(function (req, res) {
        // 处理网站图标请求
        if (req.url === '/favicon.ico') {
            res.end();
            return false;
        }
        //showMem();
        const targets = ProxyMatch.match(req, cache);
        if (targets) {
            return proxy.web(req, res, {
                target: targets[0]
            });
        }
        res.writeHead(404);
        res.write('not found');
        res.end();
    }).listen(port);
}

const getServiceWatchConfig = servie => {
    return {
        service: servie,
        success: (data, res) => {
            if (data.length > 0) {
                const serviceArray = [];
                const targetArray = [];
                data.forEach(item => {
                    // 构建Service对象实例
                    const serviceModel = new ServiceModel();
                    const { Service: { ID, Service, Tags, Address, Port } } = item;
                    Object.assign(serviceModel, {
                        ServiceId: ID,
                        Address: Address,
                        Port: Port,
                        Tags: Tags,
                    });
                    serviceArray.push(serviceModel);
                    targetArray.push(`http://${Address}:${Port}`);
                });
                cache.setService(servie, serviceArray);
                const routeConfig = new RouteConfig();
                routeConfig.targets = targetArray;
                cache.setRouteRule(`/${servie}`, routeConfig);
            } else {
                cache.setService(servie, null);
                cache.setRouteRule(`/${servie}`, null);
            }
        },
        error: err => {
            cache.setService(servie, null);
            cache.setRouteRule(`/${servie}`, null);
        }
    }
}
// 开启服务数据监听
watch.list({
    success: (data, res) => {
        for (const item in data) {
            // 判断键是否存在并去除consul服务
            if (data.hasOwnProperty(item) && item !== 'consul') {
                watch.service(getServiceWatchConfig(item));
            }
        }
    },
    error: err => {
        console.log(err);
    }
});
